﻿/******************************************
 * ITESM CEM 12 de septiembre de 2010
 * Actividad Breakout 2a parte
 * Alejandro Jesús Morales Torres
 * Gerardo Samuel Cabello Montes de Oca
 * 1161376
 * 965042
 * *****************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace BreakoutAlexMetal
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class BreakoutAlex : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Rectangle viewPortRect;
        Bloque[] bloques;
        int numBloques = 39;
        Raqueta raqueta;
        Raqueta raqueta2;
        Pelota pelota;
        Pelota pelota2;
        Rectangle[] bloquesRect;
        Rectangle raquetaRect;
        Rectangle pelotaRect;
        Rectangle pelotaRect2;
        double tiempoTranscurrido;
        double realTime;
        //double tiempoMuerte;
        private Texture2D fondo;
        SpriteFont font;
        Vector2 posTime = new Vector2(300.0f, 0.1f);
        Vector2 posScore = new Vector2(0.1f, 0.1f);
        Vector2 porLives = new Vector2(700.0f, 0.1f);
        int score = 0;
        int lives = 0;
        int time = 0;
        Explosion explosion;
        double explosionTime;
        int level = 1;

        //audio
        private SoundEffect explosionSound;
        private SoundEffect GameOverSound;
        private SoundEffect tackSound;
        private Song backMusic;


        public BreakoutAlex()
        {
            graphics = new GraphicsDeviceManager(this);

            graphics.PreferredBackBufferWidth = 806;
            graphics.PreferredBackBufferHeight = 700;


            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            viewPortRect = new Rectangle(0, 0,
                graphics.GraphicsDevice.Viewport.Width,
                graphics.GraphicsDevice.Viewport.Height);

            fondo = Content.Load<Texture2D>("graphics\\fondo");

            bloques = new Bloque[numBloques];
            bloquesRect = new Rectangle[numBloques];

            for (int i = 0; i < numBloques; i++)
            {
                bloques[i] = new Bloque(Content.Load<Texture2D>("graphics\\bloque"));
            }

            int bloquesCont = 0;

            for (int i = 0; i < 13; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                        bloques[bloquesCont].setPosition(new Vector2(i * 62, j * 31));
                        bloquesRect[bloquesCont] = new Rectangle((int)bloques[bloquesCont].getPosition().X,
                                                                 (int)bloques[bloquesCont].getPosition().Y,
                                                                 60, 30);
                        bloquesCont++;
                }
            }

            raqueta = new Raqueta(Content.Load<Texture2D>("graphics\\raqueta"));
            raqueta.setPosition(new Vector2(363.0f, 600.0f));
            raquetaRect = new Rectangle((int)raqueta.getPosition().X, (int)raqueta.getPosition().Y, 60, 30);
            lives = raqueta.getVidas();

            pelota = new Pelota(Content.Load<Texture2D>("graphics\\pelota"));
            pelota.setPosition(new Vector2(400.0f, 350.0f));
            pelotaRect = new Rectangle((int)pelota.getPosition().X, (int)pelota.getPosition().Y, 30, 30);

            if (level == 2)
            {
                pelota2 = new Pelota(Content.Load<Texture2D>("graphics\\pelota"));
                pelota2.setPosition(new Vector2(400.0f, 350.0f));
                pelotaRect2 = new Rectangle((int)pelota2.getPosition().X, (int)pelota2.getPosition().Y, 30, 30);
                pelota2.rebotarHorizontal();
                pelota2.rebotarVertical();
            }


            font = Content.Load<SpriteFont>("graphics\\font");

            explosion = new Explosion(Content.Load<Texture2D>("graphics\\explosion2"), 16, 100, new Point(32, 32));
            explosion.setPosition(new Vector2(900.0f, 900.0f));

            //audio
            explosionSound = Content.Load<SoundEffect>("sound\\explo");
            GameOverSound  = Content.Load<SoundEffect>("sound\\GO");
            tackSound  = Content.Load<SoundEffect>("sound\\tack");
            backMusic = Content.Load<Song>("backSound");
            MediaPlayer.Play(backMusic);

        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            pelota.moverHorizontal();
            pelotaRect.X = (int)pelota.getPosition().X;
            pelota.moverVertical();
            pelotaRect.Y = (int)pelota.getPosition().Y;

            if (level == 2)
            {
                pelota2.moverHorizontal();
                pelotaRect2.X = (int)pelota2.getPosition().X;
                pelota2.moverVertical();
                pelotaRect2.Y = (int)pelota2.getPosition().Y;
            }

            explosionTime += gameTime.ElapsedGameTime.TotalMilliseconds;
            realTime += gameTime.ElapsedGameTime.TotalMilliseconds;
            if (realTime > 1000 && raqueta.isVivo())
            {
                time++;
                realTime = 0;
            }
            //if ((int)gameTime.ElapsedGameTime.TotalSeconds % 7 == 1)
            //if ((int)gameTime.ElapsedRealTime.TotalSeconds % 1000 == 0)
            tiempoTranscurrido += gameTime.ElapsedGameTime.TotalMilliseconds;
            

            if (tiempoTranscurrido > 2000 && raqueta.isVivo())
            {
                for(int i = 0; i < bloques.Length; i++)
                {
                    if (bloques[i].isActivo())
                    {

                        //bloques[i].setPosition(new Vector2(bloques[i].getPosition().X,
                                                            //bloques[i].getPosition().Y + 20));
                        //bloquesRect[i].X = (int)bloques[i].getPosition().X;
                        bloques[i].bajar();
                        bloquesRect[i].Y = (int)bloques[i].getPosition().Y;
                        if (bloquesRect[i].Y >= 700 - 30)
                        {
                            raqueta.matar(raqueta.getVidas());
                        }
                    }
                    tiempoTranscurrido = 0;
                }
                
            }

            KeyboardState kState = Keyboard.GetState();

            if (kState.IsKeyDown(Keys.Left) && raqueta.getPosition().X > 0)
            {
                raqueta.izquierda();
                raquetaRect.X = (int)raqueta.getPosition().X;
            }


            if (kState.IsKeyDown(Keys.Right) && raqueta.getPosition().X < (806 - 60))
            {
                raqueta.derecha();
                raquetaRect.X = (int)raqueta.getPosition().X;
            }

            ///////////////////////////////////////

            if (pelotaRect.Intersects(raquetaRect))
            {
                pelota.rebotarVertical();
                pelotaRect.Y = (int)pelota.getPosition().Y;
                tackSound.Play();
            }
            

            else if (pelota.getPosition().X <= 0)
            {
                pelota.rebotarHorizontal();
                pelotaRect.X = (int)pelota.getPosition().X;
            }
            else if (pelota.getPosition().X + 30 >= 806)
            {
                pelota.rebotarHorizontal();
                pelotaRect.X = (int)pelota.getPosition().X;
            }
            else if (pelota.getPosition().Y <= 0)
            {
                pelota.rebotarVertical();
                pelotaRect.Y = (int)pelota.getPosition().Y;
            }
            else if (pelota.getPosition().Y + 30 >= 700)
            {
                pelota.setPosition(new Vector2(400.0f, 350.0f));
                pelotaRect.X = (int)pelota.getPosition().X;
                pelotaRect.Y = (int)pelota.getPosition().Y;
                raqueta.matar(1);
                pelota.resetVelocidad();

            }
            else
            {
                for (int i = 0; i < bloques.Length; i++)
                {
                    if (pelotaRect.Intersects(bloquesRect[i]))
                    {
                        explosion.setPosition(new Vector2(bloquesRect[i].X, bloquesRect[i].Y));
                        explosionTime = 0;
                        explosion.resetIndiceAnimacion();
                        bloquesRect[i] = Rectangle.Empty;
                        bloques[i].borrar();
                        pelota.rebotarVertical();
                        pelota.aumentarVelocidad(i);
                        pelotaRect.Y = (int)pelota.getPosition().Y;
                        explosionSound.Play();
                        score += 100;
  
                    }
                }
            }

            ///////////////////////////////////////

            if (level == 2)
            {

                if (pelotaRect2.Intersects(raquetaRect))
                {
                    pelota2.rebotarVertical();
                    pelotaRect2.Y = (int)pelota2.getPosition().Y;
                    tackSound.Play();
                }


                else if (pelota2.getPosition().X <= 0)
                {
                    pelota2.rebotarHorizontal();
                    pelotaRect2.X = (int)pelota2.getPosition().X;
                }
                else if (pelota2.getPosition().X + 30 >= 806)
                {
                    pelota2.rebotarHorizontal();
                    pelotaRect2.X = (int)pelota2.getPosition().X;
                }
                else if (pelota2.getPosition().Y <= 0)
                {
                    pelota2.rebotarVertical();
                    pelotaRect2.Y = (int)pelota2.getPosition().Y;
                }
                else if (pelota2.getPosition().Y + 30 >= 700)
                {
                    pelota2.setPosition(new Vector2(400.0f, 350.0f));
                    pelotaRect2.X = (int)pelota2.getPosition().X;
                    pelotaRect2.Y = (int)pelota2.getPosition().Y;
                    raqueta.matar(1);
                    pelota2.resetVelocidad();

                }
                else
                {
                    for (int i = 0; i < bloques.Length; i++)
                    {
                        if (pelotaRect2.Intersects(bloquesRect[i]))
                        {
                            explosion.setPosition(new Vector2(bloquesRect[i].X, bloquesRect[i].Y));
                            explosionTime = 0;
                            explosion.resetIndiceAnimacion();
                            bloquesRect[i] = Rectangle.Empty;
                            bloques[i].borrar();
                            pelota2.rebotarVertical();
                            pelota2.aumentarVelocidad(i);
                            pelotaRect2.Y = (int)pelota2.getPosition().Y;
                            score += 100;
                            explosionSound.Play();
                        }
                    }
                }
            }
            /////////////////////////////////////////

            if (!raqueta.isVivo())
            {
                pelota.detener();
                if (level == 2)
                {
                    pelota2.detener();
                }
                GameOverSound.Play();
            }

            lives = raqueta.getVidas();
            /*else if(pelotaRect.Intersects(raquetaRect)){
                pelota.rebotarVertical();
                pelotaRect.Y = (int)pelota.getPosition().Y;
            }*/
            if (explosionTime < 1700)
            {
                explosion.Update(gameTime);
            }

            if (score == 1000 && level == 1)
            {
                UnloadContent();
                level = 2;
                LoadContent();
                score += 300;
            }



            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            // TODO: Add your drawing code here
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

            spriteBatch.Draw(fondo, new Rectangle(0, 0, 806, 700), Color.White);

            foreach (Bloque bloque in bloques)
            {
                if (bloque.isActivo())
                {
                    spriteBatch.Draw(bloque.getImage(),
                        bloque.getPosition(), Color.White);
                }
            }

            explosion.Draw(spriteBatch);

            spriteBatch.Draw(raqueta.getImage(), raqueta.getPosition(), Color.White);

            spriteBatch.Draw(pelota.getImage(), pelota.getPosition(), Color.White);
            if (level == 2)
            {
                spriteBatch.Draw(pelota2.getImage(), pelota2.getPosition(), Color.White);
            }
            spriteBatch.DrawString(font, "Puntos: " + score.ToString(), posScore, Color.White);

            spriteBatch.DrawString(font, "Vidas: " + lives.ToString(), porLives, Color.White);

            spriteBatch.DrawString(font, "Tiempo: " + time.ToString(), posTime, Color.White);

            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}
